package com.suning.sawp.service.impl.mainpushnew;

import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.Date;
import java.util.HashMap;
import java.util.HashSet;
import java.util.List;
import java.util.Map;
import java.util.Set;

import javax.annotation.Resource;

import org.apache.commons.collections.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import com.google.common.base.Function;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.suning.framework.dal.client.DalClient;
import com.suning.sawp.constants.ClerkConstants;
import com.suning.sawp.dto.mainpush.MainPushModelDto;
import com.suning.sawp.dto.mainpush.MainPushTaskDetailResponse;
import com.suning.sawp.dto.mainpush.RedPointDto;
import com.suning.sawp.dto.mainpush.StoreManDto;
import com.suning.sawp.dto.storeman.Category;
import com.suning.sawp.intf.dao.task.OrgRespmanDaoService;
import com.suning.sawp.intf.mainpushnew.MainPushClientService;
import com.suning.sawp.intf.model.ModelConstant;
import com.suning.sawp.intf.storeman.StoreManService;
import com.suning.sawp.intf.taskCard.vo.TaskCardVo;
import com.suning.sawp.po.mainpushnew.StoreTask;
import com.suning.sawp.po.task.OrgRespman;
import com.suning.sawp.service.util.DJStringUtils;
import com.suning.sawp.service.util.DateUtils;
import com.suning.sawp.vo.mainpushnew.ModelStatusVo;
import com.suning.sawp.vo.mainpushnew.StoreTaskInfoVo;

/**
 * 客户端主推任务服务 〈一句话功能简述〉<br>
 * 〈功能详细描述〉
 *
 * @author 15050519
 * @see [相关类/方法]（可选）
 * @since [产品/模块版本] （可选）
 */
@Service
public class MainPushClientServiceImpl implements MainPushClientService {

    /**
     * 日志
     */
    private static final Logger LOGGER = LoggerFactory.getLogger(MainPushClientServiceImpl.class);
    
    @Resource
    DalClient dalClient;

    /**
     * 店员服务
     */
    @Autowired
    StoreManService storeManService;

    /**
     * 干系人服务
     */
    @Autowired
    OrgRespmanDaoService orgRespmanDaoService;

    /**
     * 查询店长督导店员主推任务
     */
    @Override
    public List<TaskCardVo> queryMainPushTaskList(String staffId) {
        // 查询店员信息
        StoreManDto storeMan = storeManService.queryStoreManAttachInfo(staffId);
        // 1. 判断店员是店长, 督导, 还是其他(店员)
        if (checkPosition(storeMan.getPositionId())) {
            Map<String, Object> paramMap = new HashMap<String, Object>();
            List<Category> cates = storeMan.getCategories();
            // 增加品类入参
            if (CollectionUtils.isNotEmpty(cates)) {
                // 取品类集合
                paramMap.put("cateCodes", Lists.transform(cates, new Function<Category, String>() {
                    @Override
                    public String apply(Category input) {
                        return input.getCategoryCode();
                    }
                }));
            } else {
                paramMap.put("cateCodes", Lists.newArrayList(""));
            }
            // 门店编码
            paramMap.put("storeCode", storeMan.getStoreCode());
            // 当前月份
            paramMap.put("month", DateUtils.getThisMonth());
            // 查询主推任务列表
            List<StoreTaskInfoVo> tasks = dalClient.queryForList("MAIN_PUSH_CLIENT.QUERY_MAIN_PUSH_LIST", paramMap,
                    StoreTaskInfoVo.class);
            // 主推任务不为空时, 查询任务状态
            if (CollectionUtils.isNotEmpty(tasks)) {
                // 门店任务ID
                paramMap.put("taskIds", Lists.transform(tasks, new Function<StoreTaskInfoVo, Long>() {
                    @Override
                    public Long apply(StoreTaskInfoVo input) {
                        return input.getStoreTaskId();
                    }
                }));
                // 总部任务ID
                paramMap.put("hqTaskId", tasks.get(0).getHqTaskId());
                // 查询任务主推分配状态
                List<ModelStatusVo> status = dalClient.queryForList("MAIN_PUSH_CLIENT.QUERY_MAIN_PUSH_STATUS", paramMap,
                        ModelStatusVo.class);
                // 转换任务数据
                return convertTaskCard(tasks, status);
            }
        } else {
            // 店员主推任务数据查询
            Map<String, Object> paramMap = new HashMap<String, Object>();
            // 工号
            paramMap.put("staffId", staffId);
            // 门店编码
            paramMap.put("storeCode", storeMan.getStoreCode());
            // 当前月份
            paramMap.put("month", DateUtils.getThisMonth());
            // 查询店员分配的主推任务列表
            List<StoreTaskInfoVo> tasks = dalClient.queryForList("MAIN_PUSH_CLIENT.QUERY_MAIN_PUSH_STAFF", paramMap,
                    StoreTaskInfoVo.class);
            // 查询店员主推任务商品销售数据
            List<StoreTaskInfoVo> sales = dalClient.queryForList("MAIN_PUSH_CLIENT.QUERY_MAIN_PUSH_STAFF_SALE",
                    paramMap, StoreTaskInfoVo.class);
            // 转换员工主推任务数据
            return convertStaffTaskCard(tasks, sales);
        }
        return Collections.emptyList();
    }

    /**
     * 转换员工主推任务数据 功能描述: <br>
     * 〈功能详细描述〉
     *
     * @param tasks
     * @param sales
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    private List<TaskCardVo> convertStaffTaskCard(List<StoreTaskInfoVo> tasks, List<StoreTaskInfoVo> sales) {
        List<TaskCardVo> cards = new ArrayList<TaskCardVo>();
        TaskCardVo card;
        // 分配不为空时,销售为空
        if (CollectionUtils.isNotEmpty(tasks) && CollectionUtils.isEmpty(sales)) {
            for (StoreTaskInfoVo task : tasks) {
                card = new TaskCardVo();
                card.setBizKey("10006");
                card.setCardType("003");
                card.setCateCode(task.getCateCode());
                // 品类名称
                card.setTitle(task.getCateName());
                // 销售总数
                card.setFirstNum("0");
                // 目标总数
                card.setSecondNum(StringUtils.isBlank(task.getTargetNum()) ? "" : task.getTargetNum());
                // 销售额
                card.setThirdNum("0.00");
                cards.add(card);
            }
        } else if (CollectionUtils.isEmpty(tasks) && CollectionUtils.isNotEmpty(sales)) {
            // 分配为空,销售不为空
            for (StoreTaskInfoVo task : sales) {
                card = new TaskCardVo();
                card.setBizKey("10006");
                card.setCardType("003");
                card.setCateCode(task.getCateCode());
                // 没有品类名称,根据编码转换
                card.setTitle(ModelConstant.getCommCateValue(task.getCateCode()));
                // 销售总数
                card.setFirstNum(StringUtils.isBlank(task.getSaleVolume()) ? "0" : task.getSaleVolume());
                // 目标总数
                card.setSecondNum("");
                // 销售额
                card.setThirdNum(StringUtils.isBlank(task.getSaleAmount()) ? "0.00"
                        : DJStringUtils.getTwoScale(task.getSaleAmount()));
                cards.add(card);
            }
        } else if (CollectionUtils.isNotEmpty(tasks) && CollectionUtils.isNotEmpty(sales)) {
            // 分配,销售都不为空
            // 将销售数据转换成MAP对象,方便取对应品类销售数据
            Map<String, StoreTaskInfoVo> saleMap = Maps.uniqueIndex(sales, new Function<StoreTaskInfoVo, String>() {
                @Override
                public String apply(StoreTaskInfoVo input) {
                    return input.getCateCode();
                }
            });
            StoreTaskInfoVo staffSale;
            // 已处理的品类
            Set<String> hasReturn = new HashSet<String>();
            // 遍历分配的数据
            for (StoreTaskInfoVo task : tasks) {
                card = new TaskCardVo();
                card.setBizKey("10006");
                card.setCardType("003");
                card.setCateCode(task.getCateCode());
                // 品类名称
                card.setTitle(task.getCateName());
                // 目标总数
                card.setSecondNum(StringUtils.isBlank(task.getTargetNum()) ? "" : task.getTargetNum());
                // 查询店员销售数据
                staffSale = saleMap.get(task.getCateCode());
                // 不为空时
                if (null != staffSale) {
                    // 销售总数
                    card.setFirstNum(StringUtils.isBlank(staffSale.getSaleVolume()) ? "0" : staffSale.getSaleVolume());
                    // 销售额
                    card.setThirdNum(StringUtils.isBlank(staffSale.getSaleAmount()) ? "0.00"
                            : DJStringUtils.getTwoScale(staffSale.getSaleAmount()));
                } else {
                    // 销售总数
                    card.setFirstNum("0");
                    // 销售额
                    card.setThirdNum("0.00");
                }
                hasReturn.add(task.getCateCode());
                cards.add(card);
            }
            // 遍历销售主推商品数据
            for (StoreTaskInfoVo task : sales) {
                // 返回的不处理
                if (hasReturn.contains(task.getCateCode())) {
                    continue;
                }
                card = new TaskCardVo();
                card.setBizKey("10006");
                card.setCardType("003");
                card.setCateCode(task.getCateCode());
                // 没有品类名称,根据编码转换
                card.setTitle(ModelConstant.getCommCateValue(task.getCateCode()));
                // 销售总数
                card.setFirstNum(StringUtils.isBlank(task.getSaleVolume()) ? "0" : task.getSaleVolume());
                // 目标总数
                card.setSecondNum("");
                // 销售额
                card.setThirdNum(StringUtils.isBlank(task.getSaleAmount()) ? "0.00"
                        : DJStringUtils.getTwoScale(task.getSaleAmount()));
                cards.add(card);
            }
        }
        return cards;
    }

    /**
     * 转换店长督导品类任务及状态 功能描述: <br>
     * 〈功能详细描述〉
     *
     * @param tasks
     * @param status
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    private List<TaskCardVo> convertTaskCard(List<StoreTaskInfoVo> tasks, List<ModelStatusVo> status) {
        List<TaskCardVo> cards = new ArrayList<TaskCardVo>();
        TaskCardVo card;
        // 转换品类状态
        Map<String, String> statsMap = convertStatus(status);
        String cateStatus;
        // 迭代任务
        for (StoreTaskInfoVo task : tasks) {
            card = new TaskCardVo();
            card.setBizKey("10006");
            card.setCardType("003");
            card.setCateCode(task.getCateCode());
            // 品类名称
            card.setTitle(task.getCateName());
            // 销售总数
            card.setFirstNum(StringUtils.isBlank(task.getSaleVolume()) ? "0" : task.getSaleVolume());
            // 目标总数
            card.setSecondNum(StringUtils.isBlank(task.getTargetNum()) ? "" : task.getTargetNum());
            // 销售额
            card.setThirdNum(StringUtils.isBlank(task.getSaleAmount()) ? "0.00"
                    : DJStringUtils.getTwoScale(task.getSaleAmount()));
            cateStatus = statsMap.get(task.getCateCode());
            // 没有状态时默认0-未分配
            if (StringUtils.isBlank(cateStatus)) {
                card.setTaskStatus("0");
            } else {
                card.setTaskStatus(cateStatus);
            }
            cards.add(card);
        }
        return cards;
    }

    /**
     * 转换款数状态为品类状态 功能描述: <br>
     * 〈功能详细描述〉
     *
     * @param status
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    private Map<String, String> convertStatus(List<ModelStatusVo> status) {
        Map<String, String> statusString = new HashMap<String, String>();
        if (CollectionUtils.isNotEmpty(status)) {
            for (ModelStatusVo sv : status) {
                // 大区未分配款数,或者款数分配状态是未分配 且品类下不存在重新分配款数
                if ((null == sv.getStoreModelId() || "0".equals(sv.getStatus()))
                        && !"2".equals(statusString.get(sv.getCateCode()))) {
                    statusString.put(sv.getCateCode(), "0");
                } else if ("2".equals(sv.getStatus())) {
                    // 款数是重新分配
                    statusString.put(sv.getCateCode(), "2");
                } else if ("1".equals(sv.getStatus()) && null == statusString.get(sv.getCateCode())) {
                    // 款数是分配完成且品类不存在其他状态
                    statusString.put(sv.getCateCode(), "1");
                }
            }
        }
        return statusString;
    }

    /**
     * 判断是否店长或者督导 功能描述: <br>
     * 〈功能详细描述〉
     *
     * @param positionId
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    private boolean checkPosition(String positionId) {
        if (ClerkConstants.STORE_KEEPER.equals(positionId) || ClerkConstants.DEPUTY_STORE_KEEPER.equals(positionId)
                || ClerkConstants.SALE_GUIDE.equals(positionId)) {
            return true;
        }
        return false;
    }

    /**
     * 查询主推任务详情
     */
    @Override
    public MainPushTaskDetailResponse queryMainPushTaskInfo(String storeTaskId, String staffId) {
        MainPushTaskDetailResponse resp = new MainPushTaskDetailResponse();
        // 查询店员信息
        StoreManDto storeMan = storeManService.queryStoreManAttachInfo(staffId);
        // 查询主推详情
        OrgRespman orgMan = orgRespmanDaoService.getOrgRespman(storeMan.getRegionCode(),
                OrgRespman.Attributes.REGION_LEVEL);
        if (null != orgMan) {
            // 大区干系人,发件人
            resp.setSender(orgMan.getStaffName() + "(" + orgMan.getStaffCode() + ")");
        } else {
            resp.setSender("--");
        }
        // 根据门店主键查询门店主推任务
        StoreTask storeTask = queryStoreTask(storeTaskId);
        // 主推任务不存在,返回
        if (null == storeTask) {
            return resp;
        }
        // 发件时间
        resp.setSendTime(DateUtils.getDateStrByFormat(storeTask.getCreateTime(), null));
        Map<String, Object> paramMap = new HashMap<String, Object>();
        // 总部任务ID
        paramMap.put("hqTaskId", storeTask.getHqTaskId());
        // 品类编码
        paramMap.put("cateCode", storeTask.getCateCode());
        // 门店任务ID
        paramMap.put("storeTaskId", storeTaskId);
        // 查询出品类下所有的款数数据
        List<MainPushModelDto> modelList = dalClient.queryForList("MAIN_PUSH_CLIENT.QUERY_MAIN_PUSH_MODELS", paramMap, MainPushModelDto.class);
        // 款数为空时,返回
        if (CollectionUtils.isEmpty(modelList)) {
            return resp;
        }
        resp.setList(modelList);
        // 工号
        paramMap.put("staffId", staffId);
        // 门店编码
        paramMap.put("storeCode", storeMan.getStoreCode());
        // 月份
        paramMap.put("month", DateUtils.getThisMonth());
        // 款数
        paramMap.put("modelIds", Lists.transform(modelList, new Function<MainPushModelDto, Long>() {
            @Override
            public Long apply(MainPushModelDto input) {
                return Long.valueOf(input.getModelId());
            }
        }));
        // 根据款数, 工号查询款数的小红点
        List<RedPointDto> redList = dalClient.queryForList("MAIN_PUSH_CLIENT.QUERY_MAIN_PUSH_MODEL_RED_POINT", paramMap, RedPointDto.class);
        // 将小红点转换成MAP，方便调取
        Map<String, RedPointDto> redMap = new HashMap<String, RedPointDto>();
        // 保存已读小红点集合
        List<RedPointDto> toRead = new ArrayList<RedPointDto>();
        // 红点为空时
        if (CollectionUtils.isNotEmpty(redList)) {
            // 红点不为空时
            for (RedPointDto red : redList) {
                if (StringUtils.isBlank(red.getStaffId()) && !redMap.containsKey(red.getModelId().toString())) {
                    redMap.put(red.getModelId().toString(), red);
                } else if (StringUtils.isBlank(red.getStaffId())) {
                    // 设置工号,保存为已读
                    red.setStaffId(staffId);
                    // 同款数有多个小红点时，显示一个，但是所有小红点需一次清空
                    toRead.add(red);
                }
            }
        }
        
        RedPointDto point;
        StringBuilder tips = new StringBuilder("本月主推的任务");
        boolean hot = false;
        Set<String> hasUpdate = new HashSet<String>();
        for (MainPushModelDto model : modelList) {
            point = redMap.get(model.getModelId());
            // 工号为空时,说明红点并没有被消耗
            if (null != point) {
                hot = true;
                // 显示小红点
                model.setHot(true);
                // 0是新增款数，1是修改门店数量
                if ("0".equals(point.getChangeType().toString())) {
                    tips.append("新增\"" + model.getModelName() + "\", ");
                } else if ("1".equals(point.getChangeType().toString()) && !hasUpdate.contains(model.getModelId() + "&" + model.getTaskType())) {
                    tips.append("\"" + model.getModelName() + "\"发生变更, ");
                    // 变更信息已添加
                    hasUpdate.add(model.getModelId() + "&" + model.getTaskType());
                }
                // 设置工号,保存为已读
                point.setStaffId(staffId);
                toRead.add(point);
            }
            // 比较目标台数,分配台数, 显示分配按钮,或者详情按钮
            if (compareTargetNum(model.getTargetNum(), model.getDistNum())) {
                // 1-显示详情按钮
                model.setIsShow(1);
            }
        }
        // 分配的排在前面
        Collections.sort(modelList, new Comparator<MainPushModelDto> (){
            @Override
            public int compare(MainPushModelDto o1, MainPushModelDto o2) {
                return o1.getIsShow() - o2.getIsShow();
            }
        });
        // 存在小红点,提示信息
        if (hot) {
            tips.append("请按照新目标重新分配任务。");
            resp.setTips(tips.toString());
            // 将小红点置已读
            batchInsertHasRedPoint(toRead);
        }
        // 返回结果
        return resp;
    }
    
    /**
     * 比较任务的目标台数和分配台数的大小
     * 功能描述: <br>
     * 控制客户端显示分配按钮或者详情按钮
     * 〈功能详细描述〉
     *
     * @param targetNum
     * @param distNum
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    private boolean compareTargetNum(String targetNum, String distNum) {
        // 都不为空时,比较数字大小
        if (StringUtils.isNotBlank(distNum)) {
            try {
                Long dist = Long.valueOf(distNum);
                // 大区分配为空,店长分配大于0,显示详情按钮
                if (StringUtils.isBlank(targetNum) && dist > 0) {
                    return true;
                }
                // 如果大区分配不为空
                if (StringUtils.isNotBlank(targetNum)) {
                    Long target = Long.valueOf(targetNum);
                    // 当目标台数小于等于分配台数,显示详情按钮
                    return target <= dist ? true : false;
                }
            } catch (Exception e) {
                LOGGER.error("compareTargetNum error,", e);
            }
        }
        return false;
    }
    
    /**
     * 批量保存已读小红点
     * 功能描述: <br>
     * 〈功能详细描述〉
     *
     * @param toRead
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    private void batchInsertHasRedPoint(List<RedPointDto> toRead) {
        // 集合为空不处理
        if (CollectionUtils.isEmpty(toRead)) {
            return;
        }
        @SuppressWarnings("unchecked")
        Map<String, Object>[] params = new Map[toRead.size()];
        Map<String, Object> param = null;
        RedPointDto tip = null;
        Date now = new Date();
        for (int i = 0; i < toRead.size(); i++) {
            tip = toRead.get(i);
            param = new HashMap<String, Object>();
            param.put("tipsId", tip.getId());
            param.put("staffId", tip.getStaffId());
            param.put("readTime", now);
            params[i] = param;
        }
        try {
            dalClient.batchUpdate("redPoint.HAS_READ", params);
        } catch (Exception e) {
            LOGGER.error("batchInsertHasRedPoint error,", e);
        }
    }

    /**
     * 判断门店任务是否存在
     */
    @Override
    public boolean isExistTask(String storeTaskId) {
        StoreTask storeTask = queryStoreTask(storeTaskId);
        // 任务存在
        if (null != storeTask && null != storeTask.getId() && storeTask.getId() > 0) {
            return true;
        }
        return false;
    }
    
    /**
     * 查询门店主推任务
     * 功能描述: <br>
     * 〈功能详细描述〉
     *
     * @param storeTaskId
     * @return
     * @see [相关类/方法](可选)
     * @since [产品/模块版本](可选)
     */
    private StoreTask queryStoreTask(String storeTaskId) {
        Map<String, Object> paramMap = new HashMap<String, Object>();
        paramMap.put("storeTaskId", storeTaskId);
        return dalClient.queryForObject("MAIN_PUSH_CLIENT.QUERY_STORE_TASK_BY_ID", paramMap, StoreTask.class);
    }

}
